package main

import (
	"context"
	"errors"
	"fmt"
	"golang.org/x/sync/errgroup"
	"time"
)

func main() {
	eg, ctx := errgroup.WithContext(context.Background())
	eg.Go(func() error {
		fmt.Println("doing task1")
		time.Sleep(time.Second * 5)
		//只要gorutin收到这个error，他会执行ctx.cancel  其他的gorutin会接受到（并不是直接取消，而是由内部去感知这个ctx.cancel）
		return errors.New("task1 error")
	})
	eg.Go(func() error {
		for {
			select {
			case <-time.After(time.Second):
				fmt.Println("doing task2")
			case <-ctx.Done():
				fmt.Println("task2 cancel")
				return ctx.Err()
			}
		}
	})
	eg.Go(func() error {
		for {
			select {
			case <-time.After(time.Second):
				fmt.Println("doing task3")
			case <-ctx.Done():
				fmt.Println("task3 cancel")
				return ctx.Err()
			}
		}
	})
	if err := eg.Wait(); err != nil {
		fmt.Println("task failed: ", err)
	} else {
		fmt.Println("task succeeded")
	}
}
